package com.project.thisDatabase.redis;

import com.project.annotation.model.RedisItem;
import com.project.annotation.redis.RedisComponent;
import lombok.SneakyThrows;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

@ConditionalOnProperty(name = "spring.data.redis.enable", havingValue = "true")
@Component
public class RedisSetting implements  ApplicationContextAware {

    private static ApplicationContext applicationValue;
    private static Map<String, RedisItemContent> redisItems = new HashMap<>();

    @SneakyThrows
    @Override
    public void setApplicationContext(ApplicationContext applicationcontext) throws BeansException {
        applicationValue = applicationcontext;
        String[] beanNamesForAnnotation = applicationcontext.getBeanNamesForAnnotation(RedisComponent.class);
        for(String entry : beanNamesForAnnotation){
            Class<?> type = applicationcontext.getType(entry);
            RedisComponent redisComponent = type.getAnnotation(RedisComponent.class);
            RedisItem redis = (RedisItem) applicationcontext.getBean(type);
            redis.setRedis(redisComponent.redis());
            redis.setName(redisComponent.name());
            redis.setKey(redisComponent.key());
            redis.setPrefix(redisComponent.prefix());
            redis.setSuffix(redisComponent.suffix());
            redis.setTimeout(redisComponent.timeout());

            RedisTemplate<Object,Object> redisTemplate =
                    (RedisTemplate<Object,Object>)applicationcontext.getBean(redisComponent.redis());
            RedisInnerExecutor rds = new RedisInnerExecutor();
            rds.setRedisTemplate(redisTemplate);
            rds.setRedis(redisComponent.redis());
            rds.setName(redisComponent.name());
            rds.setKey(redisComponent.key());
            rds.setPrefix(redisComponent.prefix());
            rds.setSuffix(redisComponent.suffix());
            rds.setTimeout(redisComponent.timeout());

            if (!redisItems.containsKey(redisComponent.name())) {
                redisItems.put(redisComponent.name(), new RedisItemContent());
            }

            Field exec = RedisItem.class.getDeclaredField("executor");
            exec.setAccessible(true);
            exec.set(redis, rds);

            redisItems.get(redisComponent.name()).setKey(String.format("%s%s%s", redisComponent.prefix(), redisComponent.key(), redisComponent.suffix()));
            redisItems.get(redisComponent.name()).setRedisItem(redis);
        }
    }

    public static RedisItemContent getBean(String name) {
        if (redisItems.containsKey(name)) {
            return redisItems.get(name);
        }

        return null;
    }

//    private void registerSingletonBean(String beanName, Object singletonObject) {
//        ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) applicationValue;
//        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext.getAutowireCapableBeanFactory();
//        defaultListableBeanFactory.registerSingleton(beanName, singletonObject);
//    }
}
